package com.smartandroid.sa.sherlock.internal.app;

import java.util.HashSet;
import java.util.Set;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.SpinnerAdapter;

import com.smartandroid.sa.sherlock.app.ActionBar;
import com.smartandroid.sa.sherlock.app.ActionBar.OnMenuVisibilityListener;
import com.smartandroid.sa.sherlock.app.ActionBar.OnNavigationListener;
import com.smartandroid.sa.sherlock.app.ActionBar.Tab;
import com.smartandroid.sa.sherlock.app.ActionBar.TabListener;
import com.smartandroid.sa.view.StaggeredGridView.LayoutParams;

public class ActionBarWrapper extends ActionBar implements
		android.app.ActionBar.OnNavigationListener,
		android.app.ActionBar.OnMenuVisibilityListener {
	private final Activity mActivity;
	private final android.app.ActionBar mActionBar;
	private ActionBar.OnNavigationListener mNavigationListener;
	private Set<OnMenuVisibilityListener> mMenuVisibilityListeners = new HashSet<OnMenuVisibilityListener>(
			1);
	private FragmentTransaction mFragmentTransaction;

	public ActionBarWrapper(Activity activity) {
		mActivity = activity;
		mActionBar = activity.getActionBar();
		if (mActionBar != null) {
			mActionBar.addOnMenuVisibilityListener(this);

			// Fixes issue #746
			int displayOptions = mActionBar.getDisplayOptions();
			mActionBar
					.setHomeButtonEnabled((displayOptions & DISPLAY_HOME_AS_UP) != 0);
		}
	}

	@Override
	public void setHomeButtonEnabled(boolean enabled) {
		mActionBar.setHomeButtonEnabled(enabled);
	}

	@Override
	public Context getThemedContext() {
		return mActionBar.getThemedContext();
	}

	@Override
	public void setCustomView(View view) {
		mActionBar.setCustomView(view);
	}

	@Override
	public void setCustomView(View view, LayoutParams layoutParams) {
		android.app.ActionBar.LayoutParams lp = new android.app.ActionBar.LayoutParams(
				layoutParams);
		lp.gravity = layoutParams.gravity;
		lp.bottomMargin = layoutParams.bottomMargin;
		lp.topMargin = layoutParams.topMargin;
		lp.leftMargin = layoutParams.leftMargin;
		lp.rightMargin = layoutParams.rightMargin;
		mActionBar.setCustomView(view, lp);
	}

	@Override
	public void setCustomView(int resId) {
		mActionBar.setCustomView(resId);
	}

	@Override
	public void setIcon(int resId) {
		mActionBar.setIcon(resId);
	}

	@Override
	public void setIcon(Drawable icon) {
		mActionBar.setIcon(icon);
	}

	@Override
	public void setLogo(int resId) {
		mActionBar.setLogo(resId);
	}

	@Override
	public void setLogo(Drawable logo) {
		mActionBar.setLogo(logo);
	}

	@Override
	public void setListNavigationCallbacks(SpinnerAdapter adapter,
			OnNavigationListener callback) {
		mNavigationListener = callback;
		mActionBar.setListNavigationCallbacks(adapter,
				(callback != null) ? this : null);
	}

	@Override
	public boolean onNavigationItemSelected(int itemPosition, long itemId) {
		// This should never be a NullPointerException since we only set
		// ourselves as the listener when the callback is not null.
		return mNavigationListener.onNavigationItemSelected(itemPosition,
				itemId);
	}

	@Override
	public void setSelectedNavigationItem(int position) {
		mActionBar.setSelectedNavigationItem(position);
	}

	@Override
	public int getSelectedNavigationIndex() {
		return mActionBar.getSelectedNavigationIndex();
	}

	@Override
	public int getNavigationItemCount() {
		return mActionBar.getNavigationItemCount();
	}

	@Override
	public void setTitle(CharSequence title) {
		mActionBar.setTitle(title);
	}

	@Override
	public void setTitle(int resId) {
		mActionBar.setTitle(resId);
	}

	@Override
	public void setSubtitle(CharSequence subtitle) {
		mActionBar.setSubtitle(subtitle);
	}

	@Override
	public void setSubtitle(int resId) {
		mActionBar.setSubtitle(resId);
	}

	@Override
	public void setDisplayOptions(int options) {
		mActionBar.setDisplayOptions(options);

		// Fixes issue #746
		mActionBar.setHomeButtonEnabled((options & DISPLAY_HOME_AS_UP) != 0);
	}

	@Override
	public void setDisplayOptions(int options, int mask) {
		mActionBar.setDisplayOptions(options, mask);

		// Fixes issue #746
		if ((mask & DISPLAY_HOME_AS_UP) != 0) {
			mActionBar
					.setHomeButtonEnabled((options & DISPLAY_HOME_AS_UP) != 0);
		}
	}

	@Override
	public void setDisplayUseLogoEnabled(boolean useLogo) {
		mActionBar.setDisplayUseLogoEnabled(useLogo);
	}

	@Override
	public void setDisplayShowHomeEnabled(boolean showHome) {
		mActionBar.setDisplayShowHomeEnabled(showHome);
	}

	@Override
	public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
		mActionBar.setDisplayHomeAsUpEnabled(showHomeAsUp);
	}

	@Override
	public void setDisplayShowTitleEnabled(boolean showTitle) {
		mActionBar.setDisplayShowTitleEnabled(showTitle);
	}

	@Override
	public void setDisplayShowCustomEnabled(boolean showCustom) {
		mActionBar.setDisplayShowCustomEnabled(showCustom);
	}

	@Override
	public void setBackgroundDrawable(Drawable d) {
		mActionBar.setBackgroundDrawable(d);
	}

	@Override
	public void setStackedBackgroundDrawable(Drawable d) {
		mActionBar.setStackedBackgroundDrawable(d);
	}

	@Override
	public void setSplitBackgroundDrawable(Drawable d) {
		mActionBar.setSplitBackgroundDrawable(d);
	}

	@Override
	public View getCustomView() {
		return mActionBar.getCustomView();
	}

	@Override
	public CharSequence getTitle() {
		return mActionBar.getTitle();
	}

	@Override
	public CharSequence getSubtitle() {
		return mActionBar.getSubtitle();
	}

	@Override
	public int getNavigationMode() {
		return mActionBar.getNavigationMode();
	}

	@Override
	public void setNavigationMode(int mode) {
		mActionBar.setNavigationMode(mode);
	}

	@Override
	public int getDisplayOptions() {
		return mActionBar.getDisplayOptions();
	}

	public class TabWrapper extends ActionBar.Tab implements
			android.app.ActionBar.TabListener {
		final android.app.ActionBar.Tab mNativeTab;
		private Object mTag;
		private TabListener mListener;

		public TabWrapper(android.app.ActionBar.Tab nativeTab) {
			mNativeTab = nativeTab;
			mNativeTab.setTag(this);
		}

		@Override
		public int getPosition() {
			return mNativeTab.getPosition();
		}

		@Override
		public Drawable getIcon() {
			return mNativeTab.getIcon();
		}

		@Override
		public CharSequence getText() {
			return mNativeTab.getText();
		}

		@Override
		public Tab setIcon(Drawable icon) {
			mNativeTab.setIcon(icon);
			return this;
		}

		@Override
		public Tab setIcon(int resId) {
			mNativeTab.setIcon(resId);
			return this;
		}

		@Override
		public Tab setText(CharSequence text) {
			mNativeTab.setText(text);
			return this;
		}

		@Override
		public Tab setText(int resId) {
			mNativeTab.setText(resId);
			return this;
		}

		@Override
		public Tab setCustomView(View view) {
			mNativeTab.setCustomView(view);
			return this;
		}

		@Override
		public Tab setCustomView(int layoutResId) {
			mNativeTab.setCustomView(layoutResId);
			return this;
		}

		@Override
		public View getCustomView() {
			return mNativeTab.getCustomView();
		}

		@Override
		public Tab setTag(Object obj) {
			mTag = obj;
			return this;
		}

		@Override
		public Object getTag() {
			return mTag;
		}

		@Override
		public Tab setTabListener(TabListener listener) {
			mNativeTab.setTabListener(listener != null ? this : null);
			mListener = listener;
			return this;
		}

		@Override
		public void select() {
			mNativeTab.select();
		}

		@Override
		public Tab setContentDescription(int resId) {
			mNativeTab.setContentDescription(resId);
			return this;
		}

		@Override
		public Tab setContentDescription(CharSequence contentDesc) {
			mNativeTab.setContentDescription(contentDesc);
			return this;
		}

		@Override
		public CharSequence getContentDescription() {
			return mNativeTab.getContentDescription();
		}

		@Override
		public void onTabReselected(android.app.ActionBar.Tab tab,
				android.app.FragmentTransaction ft) {
			if (mListener != null) {
				FragmentTransaction trans = null;
				if (mActivity instanceof FragmentActivity) {
					trans = ((FragmentActivity) mActivity)
							.getSupportFragmentManager().beginTransaction()
							.disallowAddToBackStack();
				}

				mListener.onTabReselected(this, trans);

				if (trans != null && !trans.isEmpty()) {
					trans.commit();
				}
			}
		}

		@Override
		public void onTabSelected(android.app.ActionBar.Tab tab,
				android.app.FragmentTransaction ft) {
			if (mListener != null) {

				if (mFragmentTransaction == null
						&& mActivity instanceof FragmentActivity) {
					mFragmentTransaction = ((FragmentActivity) mActivity)
							.getSupportFragmentManager().beginTransaction()
							.disallowAddToBackStack();
				}

				mListener.onTabSelected(this, mFragmentTransaction);

				if (mFragmentTransaction != null) {
					if (!mFragmentTransaction.isEmpty()) {
						mFragmentTransaction.commit();
					}
					mFragmentTransaction = null;
				}
			}
		}

		@Override
		public void onTabUnselected(android.app.ActionBar.Tab tab,
				android.app.FragmentTransaction ft) {
			if (mListener != null) {
				FragmentTransaction trans = null;
				if (mActivity instanceof FragmentActivity) {
					trans = ((FragmentActivity) mActivity)
							.getSupportFragmentManager().beginTransaction()
							.disallowAddToBackStack();
					mFragmentTransaction = trans;
				}

				mListener.onTabUnselected(this, trans);
			}
		}
	}

	@Override
	public Tab newTab() {
		return new TabWrapper(mActionBar.newTab());
	}

	@Override
	public void addTab(Tab tab) {
		mActionBar.addTab(((TabWrapper) tab).mNativeTab);
	}

	@Override
	public void addTab(Tab tab, boolean setSelected) {
		mActionBar.addTab(((TabWrapper) tab).mNativeTab, setSelected);
	}

	@Override
	public void addTab(Tab tab, int position) {
		mActionBar.addTab(((TabWrapper) tab).mNativeTab, position);
	}

	@Override
	public void addTab(Tab tab, int position, boolean setSelected) {
		mActionBar.addTab(((TabWrapper) tab).mNativeTab, position, setSelected);
	}

	@Override
	public void removeTab(Tab tab) {
		mActionBar.removeTab(((TabWrapper) tab).mNativeTab);
	}

	@Override
	public void removeTabAt(int position) {
		mActionBar.removeTabAt(position);
	}

	@Override
	public void removeAllTabs() {
		mActionBar.removeAllTabs();
	}

	@Override
	public void selectTab(Tab tab) {
		mActionBar.selectTab(((TabWrapper) tab).mNativeTab);
	}

	@Override
	public Tab getSelectedTab() {
		android.app.ActionBar.Tab selected = mActionBar.getSelectedTab();
		return (selected != null) ? (Tab) selected.getTag() : null;
	}

	@Override
	public Tab getTabAt(int index) {
		android.app.ActionBar.Tab selected = mActionBar.getTabAt(index);
		return (selected != null) ? (Tab) selected.getTag() : null;
	}

	@Override
	public int getTabCount() {
		return mActionBar.getTabCount();
	}

	@Override
	public int getHeight() {
		return mActionBar.getHeight();
	}

	@Override
	public void show() {
		mActionBar.show();
	}

	@Override
	public void hide() {
		mActionBar.hide();
	}

	@Override
	public boolean isShowing() {
		return mActionBar.isShowing();
	}

	@Override
	public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
		mMenuVisibilityListeners.add(listener);
	}

	@Override
	public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
		mMenuVisibilityListeners.remove(listener);
	}

	@Override
	public void onMenuVisibilityChanged(boolean isVisible) {
		for (OnMenuVisibilityListener listener : mMenuVisibilityListeners) {
			listener.onMenuVisibilityChanged(isVisible);
		}
	}
}
